package com.hwd.gmall.web.util;

import java.io.Serializable;
import java.util.List;

/**
 * 自定义的分页类
 *
 * @author 黄伟东/Victor
 * @date 2022/5/1 13:27
 */
public class Page<T> implements Serializable {

    /**
     * 页数（第几页）
     */
    private Integer currentPage;

    /**
     * 查询数据库里面对应的数据有多少条
     * 从数据库查处的总记录数
     */
    private Long total;

    /**
     * 每页查5条
     */
    private Integer size;

    /**
     * 下页
     */
    private Integer next;

    private List<T> list;

    /**
     * 最后一页
     */
    private Integer last;

    /**
     * 开始页码
     */
    private Integer leftPage;

    /**
     * 结束页码
     */
    private Integer rightPage;

    /**
     * 从哪条开始查
     */
    private Long start;

    /**
     * 全局偏移量
     */
    public Integer offSize = 2;

    public Page() {
        super();
    }

    /**
     * 带有偏移量设置的分页
     *
     * @param total       数据总条数
     * @param currentPage 当前页码
     * @param pageSize    每页显示的数量
     * @param offSize     全局偏移量
     */
    public Page(long total, int currentPage, int pageSize, int offSize) {
        this.offSize = offSize;
        initPage(total, currentPage, pageSize);
    }

    /**
     * 设置当前页，总页数，起始数据位置
     *
     * @param currentPage 当前页码
     * @param total       总数据量
     * @param pageSize    每页显示数量
     */
    public void setCurrentPage(long total, int currentPage, int pageSize) {

        // 如果整除表示正好分N页，如果不能整除在N页的基础上+1页
        int totalPages = (int) (total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1);

        // 总页数
        this.last = totalPages;

        // 判断当前页是否越界，如果越界，我们就查最后一页
        this.currentPage = Math.min(currentPage, totalPages);

        // 计算start
        this.start = (long) (this.currentPage - 1) * pageSize;
    }

    /**
     * 获取上一页页码
     *
     * @return long
     */
    public long getUpper() {
        return currentPage > 1 ? currentPage - 1 : currentPage;
    }

    /**
     * total / pageSize
     *
     * @param last 最后一页
     */
    public void setLast(int last) {
        this.last = (int) (total % size == 0 ? total / size : (total / size) + 1);
    }

    /**
     * 不带偏移量的初始化分页
     *
     * @param total       总记录数
     * @param currentPage 当前页
     * @param pageSize    每页显示多少条
     */
    public Page(long total, int currentPage, int pageSize) {
        initPage(total, currentPage, pageSize);
    }

    /**
     * 初始化分页
     *
     * @param total       数据总条数
     * @param currentPage 当前页码
     * @param pageSize    每页显示的数量
     */
    private void initPage(long total, int currentPage, int pageSize) {
        // 总记录数
        this.total = total;
        // 每页显示多少条
        this.size = pageSize;

        // 计算当前页和数据库查询起始值以及总页数
        setCurrentPage(total, currentPage, pageSize);

        // 设置下一页页码
        this.next = this.currentPage < this.last ? this.currentPage + 1 : this.last;

        // 2点判断，正常情况下的起点
        this.leftPage = currentPage - this.offSize;
        // 正常情况下的终点
        this.rightPage = currentPage + this.offSize;

        // 页差=总页数和结束页的差，判断是否大于最大页数
        int topDiv = this.last - rightPage;

        /*
         * 起点页
         * 1、页差<0  起点页=起点页+页差值
         * 2、页差>=0 起点和终点判断
         */
        if (topDiv < 0) {
            this.leftPage = this.leftPage + topDiv;
        }

        /*
         * 结束页
         * 1、起点页<=0   结束页=|起点页|+1
         * 2、起点页>0    结束页
         */
        if (this.leftPage <= 0) {
            this.rightPage += (this.leftPage * -1) + 1;
        }

        // 当起点页<=0  让起点页为第一页，否则不管
        this.leftPage = this.leftPage <= 0 ? 1 : this.leftPage;

        // 如果结束页>总页数   结束页=总页数，否则不管
        this.rightPage = Math.min(this.rightPage, last);
    }

    public long getNext() {
        return next;
    }

    public long getCurrentPage() {
        return currentPage;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public long getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public long getLast() {
        return last;
    }

    public Integer getLeftPage() {
        return leftPage;
    }

    public Integer getRightPage() {
        return rightPage;
    }

    public void setLeftPage(int leftPage) {
        this.leftPage = leftPage;
    }

    public long getStart() {
        return start;
    }

    public void setStart(long start) {
        this.start = start;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public void setSize(Integer size) {
        this.size = size;
    }

    public void setNext(Integer next) {
        this.next = next;
    }

    public void setLast(Integer last) {
        this.last = last;
    }

    public void setLeftPage(Integer leftPage) {
        this.leftPage = leftPage;
    }

    public void setRightPage(Integer rightPage) {
        this.rightPage = rightPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public void setStart(Long start) {
        this.start = start;
    }
}
